package com.yaowk.service.system.service.impl;

import com.yaowk.api.common.StatusDict;
import com.yaowk.api.system.event.AddUserEvent;
import com.yaowk.api.system.event.LoginEvent;
import com.yaowk.api.system.model.Login;
import com.yaowk.api.system.model.User;
import com.yaowk.api.system.service.IUserService;
import com.yaowk.service.common.BaseRepository;
import com.yaowk.service.common.BaseServiceImpl;
import com.yaowk.service.system.dao.UserRepository;
import com.yaowk.service.system.entity.SysMenu;
import com.yaowk.service.system.entity.SysPermission;
import com.yaowk.service.system.entity.SysRole;
import com.yaowk.service.system.entity.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class UserServiceImpl extends BaseServiceImpl<User, SysUser, Integer> implements IUserService {

    @Autowired
    ApplicationContext applicationContext;

    @Autowired
    private UserRepository dao;

    @Override
    protected BaseRepository<SysUser, Integer> getDao() {
        return dao;
    }

    @Override
    protected SysUser model2Entity(User model) {
        SysUser sysUser = null;
        if (!ObjectUtils.isEmpty(model)) {
            sysUser = new SysUser();
            sysUser.setId(model.getId());
            sysUser.setCreateTime(model.getCreateTime());
            sysUser.setPassword(model.getPassword());
            sysUser.setStatus(model.getStatus());
            sysUser.setUsername(model.getUsername());
        }
        return sysUser;
    }

    @Override
    protected User entity2model(SysUser entity) {
        User user = null;
        if (!ObjectUtils.isEmpty(entity)) {
            user = new User();
            user.setId(entity.getId());
            user.setCreateTime(entity.getCreateTime());
            user.setPassword(entity.getPassword());
            user.setStatus(entity.getStatus());
            user.setUsername(entity.getUsername());
        }
        return user;
    }


    @Override
    @Transactional
    public void deleteById(Integer user) {
        SysUser sysUser = dao.findOne(user);
        if (!ObjectUtils.isEmpty(sysUser)) {
            sysUser.setStatus(StatusDict.DELETE);
            dao.save(sysUser);
        }
    }

    @Override
    @Transactional
    public List<String> findPermissionsByUser(User user) {
        SysUser sysUser = dao.findOne(user.getId());
        List<String> permissions = new ArrayList<>();
        for (SysRole sysRole : sysUser.getRoles()) {
            for (SysMenu sysMenu : sysRole.getMenus()) {
                for (SysPermission sysPermission : sysMenu.getPermissions()) {
                    permissions.add(sysPermission.getPermission());
                }
            }
        }
        return permissions;
    }

    @Override
    @Transactional
    public void roleEdit(Integer userId, List<Integer> roleIds) {
        SysUser sysUser = dao.findOne(userId);
        Set<SysRole> roles = new HashSet<>();
        sysUser.setRoles(roles);
        if (!CollectionUtils.isEmpty(roleIds)) {
            for (Integer id : roleIds) {
                SysRole sysRole = new SysRole();
                sysRole.setId(id);
                roles.add(sysRole);
            }
        }
        dao.save(sysUser);
    }

    @Override
    public void login(Login login) {
        System.out.println("invoke login method.....");
        System.out.println(login.toString());
        applicationContext.publishEvent(new LoginEvent(login));
    }

    @Override
    public User save(User model) {
        boolean add = false;
        if (ObjectUtils.isEmpty(model.getId())) {
            add = true;
            model = super.simpleSave(model);
        } else {
            SysUser sysUser = dao.findOne(model.getId());
            if (!StringUtils.isEmpty(model.getPassword())) {
                sysUser.setPassword(model.getPassword());
            }
            if (!ObjectUtils.isEmpty(model.getStatus())) {
                sysUser.setStatus(model.getStatus());
            }
            sysUser = dao.save(sysUser);
            model = entity2model(sysUser);
        }
        if (add) {
            applicationContext.publishEvent(new AddUserEvent(model));
        }
        return model;
    }
}
